home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /* sb.c -- Routines Sound Blaster Card & DIGPak Drivers */
- /* Copyright (c) 1995 John A. Ball */
- /* */
- /* This source is available for your own personal use only! You may make */
- /* any changes you wish but please do not distribute modified source code. */
- /* Please notify me of any errors or improvements. */
- /* */
- /* by John A. Ball July 4, 1996 */
- /***************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <malloc.h>
- #include <string.h>
- #include <sound.h>
- #include <graph.h>
-
-
- #define SB_ADDRESS 0x210 /* starting i/o address for SB */
- #define TRUE 1
- #define NOCOMPRESS 100
-
- struct SNDSTRUC snd;
- extern int debug;
- extern int verbose;
- extern int shell;
- extern int sb_info;
- extern struct CARD_INFO card_info;
- extern int volume;
- extern int compression;
- extern int magnitude;
- extern int default_bits;
- extern int stop;
- extern int repeat;
- extern int error;
- extern int multi_error;
- extern int conversion_table;
- extern unsigned int play_rate;
- extern unsigned int pitch;
- extern char _far **fbuffer;
- extern unsigned int dma_size;
-
- int sb_address=0;
- int *psb;
-
- int sb_card(void);
- int find_sb(void);
- int get_sb_info(void);
- int reset_sb(int address);
- void show_card_info(void);
- int speaker(int state);
- void delay(char tc, int period);
- int dacplay(char _far *fbuffer,int k,int frequency,int mode,int volume,int channels);
- int digplay(struct SNDSTRUC _far *sndplay);
- void show_dac_error(int error);
- int find_digpak(void);
- int get_card_type(void);
- int get_version(void);
- int play_block(struct SOUND *hp, int source_handle);
-
-
- int sb_card(void)
- {
- int error=0;
- int blaster=0;
-
- psb=&sb_info;
-
- error=get_sb_info();
- blaster=psb[4];
- if(error > 0){
- printf("Error in Sound Blaster Environment %i\n",error);
- switch(error)
- {
- case 10:
- printf("A (Address ie A220) Parameter not found!\n");
- break;
- case 20:
- printf("I (Irq ie I5) Parameter not found!\n");
- break;
- case 30:
- printf("D (DMA ie D1) Parameter not found!\n");
- break;
- case 40:
- printf("T (Type ie T3) Parameter not found!\n");
- break;
- }
- blaster=find_sb();
- }
- else{
- if((error < 0) && debug)
- printf("No BLASTER parameters found in environment\n");
- if(error < 0){
- blaster=find_sb();
- }
-
- if(!error){
- error=reset_sb(blaster);
- if(error){
- blaster=find_sb();
- printf("Environment BLASTER=A (Address) parameter is not correct.\n");
- }
- }
- if(blaster){
- psb[4]=blaster;
- }
- }
- if(blaster){
- if(reset_sb(blaster))
- printf("Sound Blaster not responding to reset!\n");
- card_info.io_addr=blaster;
- sb_address=blaster;
- }
- return(blaster);
- }
-
- /* Make sure Sound Blaster Available */
-
- int find_sb(void)
- {
- int blaster=0;
-
- _asm{
- push bx
- mov bx,0
- h0:
- mov al,1
- mov dx,SB_ADDRESS
- add dx,6
- add dx,bx
- out dx,al
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- mov al,0
- out dx,al
- add dx,4
- mov cx,0ffffh
- h1:
- in al,dx
- cmp al,0aah
- je h2
- loop h1
- add bx,010h
- cmp bx,050h
- jle h0
- mov ax,0
- mov blaster,ax
- jmp h3
- h2:
- mov ax,SB_ADDRESS
- add ax,bx
- mov blaster,ax
- h3: pop bx
- }
- if(debug && blaster)printf("Found Sound Blaster Board @ %x\n",blaster);
- return(blaster);
- }
-
- int get_sb_info(void)
- {
- char *pe;
- char v[80];
- char *pv;
- char b[80];
- int i=0;
- int error=0;
-
- pe=getenv("BLASTER");
- if(pe!=NULL){
- strcpy( v, pe );
-
- pv=strpbrk(v,"A");
- if(pv!=NULL){
- if(debug)printf("Environment parameter BLASTER=%s\n",pv);
- pv++;
- i=0;
- while(( *pv != '\x20' || '\x0' ) && i<80)
- {
- b[i]=*pv++;
- i++;
- }
- b[i]='\x0';
- i=atoi(b);
- i=(i-200)/10;
- psb[4]=0x200 + i*16;
- }
- else error=10;
-
- pv=strpbrk(v,"I");
- if(pv!=NULL){
- pv++;
- i=0;
- while((*pv != ' ' || '\0') && i<80)
- {
- b[i]=*pv++;
- i++;
- }
- b[i]='\0';
- psb[1]=atoi(b);
- }
- else error=20;
-
- pv=strpbrk(v,"D");
- if(pv!=NULL){
- pv++;
- i=0;
- while((*pv != ' ' || '\0') && i<80)
- {
- b[i]=*pv++;
- i++;
- }
- b[i]='\0';
- psb[6]=atoi(b);
- }
- else error=30;
-
- pv=strpbrk(v,"T");
- if(pv!=NULL){
- pv++;
- i=0;
- while((*pv != ' ' || '\0') && i<80)
- {
- b[i]=*pv++;
- i++;
- }
- b[i]='\0';
- psb[7]=atoi(b);
- }
- else error=40;
-
- return(error);
- }
- else return(-1);
- }
-
- int speaker(int state)
- {
- if(card_info.type==BLASTER){
- _asm{
- mov bx,state
- mov dx,sb_address
- add dx,0ch
- mov cx,0ffffh
- g_s: in al,dx
- and al,080h
- je s_ok
- loop g_s
- mov ax,1
- jmp s_end
- s_ok: cmp bx,0
- je speak_off
- mov al,0d1h
- out dx,al
- mov ax,0
- jmp s_end
- speak_off:
- mov al,0d3h
- out dx,al
- mov ax,0
- s_end:
- }
- }
- }
-
- int reset_sb(int address)
- {
- _asm{
- mov bx,0
- h0:
- mov al,1
- mov dx,address
- add dx,6
- out dx,al
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- mov al,0
- out dx,al
- add dx,4
- mov cx,0ffffh
- h1:
- in al,dx
- cmp al,0aah
- je h6
- loop h1
- mov ax,1 ;error
- jmp h3
- h6:
- add dx,4
- mov cx,0ffffh
- h4:
- in al,dx
- OR AL,AL
- JNS H2
- LOOP H4
- mov ax,1 ;error
- jmp h3
- h5:
- add bx,010h
- cmp bx,050h
- jle h0
- mov ax,1 ;error
- jmp h3
- h2:
- mov ax,0 ;ok
- h3:
- }
- }
- void show_card_info(void)
- {
- int *psb_info;
- int version=0;
-
- psb_info=&sb_info;
-
- if(debug && (card_info.type==BLASTER))printf("Sound Blaster DSP version %X I/O %x IRQ %i DMA %i Type %i\n"
- ,psb_info[5],psb_info[4],psb_info[1],psb_info[6],psb_info[7]);
- if(debug && card_info.type==DIGPAK){
- version=get_version();
- if(version==0)version=100;
- printf("DIGPAK Driver version %.2f installed!\n",(float)version/100);
- }
- if(debug && card_info.type==PCSPEAKER)printf("No sound card found using pc speaker!\n");
- }
-
- void delay(char tc, int period)
- {
- if(card_info.type==BLASTER)error=sbdelay(tc,period);
- }
-
- int dacplay(char _far *fbuffer,int k,int frequency,int mode,int volume,int channels)
- {
- int error=0;
- int flag=0;
-
- if(card_info.type==BLASTER){
- mode=(mode & 0xfffe);
-
- switch(mode)
- {
- case 0:
- error=sbdma(fbuffer,k,frequency,0,volume,channels);
- break;
- case ADPCM4:
- error=sbdma(fbuffer,k,frequency,1,volume,channels);
- break;
- case ADPCM26:
- error=sbdma(fbuffer,k,frequency,2,volume,channels);
- break;
- case ADPCM2:
- error=sbdma(fbuffer,k,frequency,3,volume,channels);
- break;
- case BIT8_S:
- error=sbdma(fbuffer,k,frequency,4,volume,channels);
- break;
- default:
- if(shell)printf("\n Type of Compression not supported! \n");
- else if(verbose)printf("Type of Compression not supported!\n");
- multi_error=TRUE;
- error=NOCOMPRESS;
- break;
- }
- }
- else if(card_info.type==DIGPAK){
-
- snd.sound=fbuffer;
- snd.sndlen=k;
- snd.IsPlaying=&flag;
- snd.frequency=frequency;
- mode=(mode & 0xfffe);
-
- switch(mode)
- {
- case 0:
- case BIT8_S:
- error=digplay(&snd);
- break;
- default:
- if(shell)printf(" Type of Compression not supported!\n");
- else if(verbose)printf("Type of Compression not supported!\n");
- multi_error=TRUE;
- error=NOCOMPRESS;
- break;
- }
- }
- return(error);
- }
-
- void show_dac_error(int error)
- {
- if(shell && (card_info.type!=PCSPEAKER)){
- _settextcolor(14);
- _settextposition(24,10);
- _outtext(" ");
- _settextposition(23,1);
- }
-
- if(card_info.type==BLASTER)printf("Problem with Sound Blaster ");
- switch(error)
- {
- case 1:
- printf("Error 1 DMA already in use!\n");
- break;
- case 2:
- printf("Error 2 IRQ not responding!\n");
- break;
- case 3:
- printf("Error 3 DSP not responding!\n");
- break;
- case 4:
- printf("Error 4 Could not read DSP version!\n");
- break;
- case 5:
- printf("Error 5 DMA channel not working (must be 0, 1, or 3)!\n");
- break;
- case 6:
- printf("Error 6 I (IRQ) parameter in environment is not correct!\n");
- break;
- case 7:
- printf("Error 7 IRQ not valid (must be 2, 3, 5, 7, or 10)!\n");
- break;
- case 8:
- printf("Error 8 number of samples is zero!\n");
- break;
- case NOCOMPRESS:
- break;
- default:
- printf("Unknown error! %i\n",error);
- break;
- }
- }
-
- /* Check for a Sound Card */
-
- int get_card_type(void)
- {
- int type=PCSPEAKER;
- if(sb_card())type=BLASTER;
- if(check_digpak())type=DIGPAK;
- return(type);
- }
-
- int check_digpak(void)
- {
-
- _asm{
- push ds
- push si
- mov si,66h*4 ;get vector number
- xor ax,ax ;zero
- mov ds,ax ;point it there
- lds si,[si] ;get address of ivec
- or si,si ;zero?
- jz ciout ;exit if zero
- sub si,6 ;point back to identifier
- cmp [si],0494dh ; 'IM' midi driver?
- jne nex
- cmp [si+2],04944h ;'ID' full midi driver identity string?
- jne nex
- ; ok, a MIDI driver is loaded at this address.
- mov ax,0701h ;digitized sound capabilities request
- int 66h
- or ax,ax
- jnz dok ;yes,
- jz ciout ;no
- nex: cmp [si],454bh
- jne ciout
- cmp [si+2],4e52h
- je dok
- ciout: xor ax,ax ;zero driver
- jmp ext
- dok: mov ax,1
- ext: pop si
- pop ds
- }
- }
-
- int get_version(void)
- {
- _asm{
- mov bx,0
- mov ax,0689h
- int 66h
- mov ax,bx
- }
- }
-
-
-